<template>
	<div class="sys-job-container">
		<el-card shadow="hover" :body-style="{ paddingBottom: '0' }">
			<el-form :model="state.queryParams" ref="queryForm" :inline="true">
				<el-form-item :label="$t('message.pageConfiguration.jobNumber1')">
					<el-input v-model="state.queryParams.jobId" :placeholder="$t('message.pageConfiguration.jobNumber1')" clearable />
				</el-form-item>
				<el-form-item :label="$t('message.pageConfiguration.description')">
					<el-input v-model="state.queryParams.description" :placeholder="$t('message.pageConfiguration.description')" clearable />
				</el-form-item>
				<el-form-item>
					<el-button-group>
						<el-button type="primary" icon="ele-Search" @click="handleQuery" v-auth="'sysJob:pageJobDetail'"> {{ $t('message.pageConfiguration.query') }} </el-button>
						<el-button icon="ele-Refresh" @click="resetQuery"> {{ $t('message.pageConfiguration.reset') }} </el-button>
					</el-button-group>
				</el-form-item>
				<el-form-item>
					<el-button-group style="margin: 0px 12px">
						<el-tooltip :content="$t('message.pageConfiguration.reset')">
							<el-button icon="ele-CirclePlus" @click="openAddJobDetail" v-auth="'sysJob:addJobDetail'"> </el-button>
						</el-tooltip>
						<el-tooltip :content="$t('message.pageConfiguration.startAllJob')">
							<el-button icon="ele-VideoPlay" @click="startAllJob" />
						</el-tooltip>
						<el-tooltip :content="$t('message.pageConfiguration.pauseAllJob')">
							<el-button icon="ele-VideoPause" @click="pauseAllJob" />
						</el-tooltip>
					</el-button-group>
					<el-button-group style="margin: 0px 12px 0px 0px">
						<el-tooltip :content="$t('message.messages.forceWakeupJob')">
							<el-button icon="ele-AlarmClock" @click="cancelSleep" />
						</el-tooltip>
						<el-tooltip :content="$t('message.messages.forceTriggerAllJob')">
							<el-button icon="ele-Connection" @click="persistAll" />
						</el-tooltip>
					</el-button-group>
					<el-button icon="ele-Coin" @click="openJobCluster" plain> {{ $t('message.pageConfiguration.cluster') }} </el-button>
					<el-button icon="ele-Grid" @click="openJobDashboard" plain> {{ $t('message.pageConfiguration.taskBoard') }} </el-button>
				</el-form-item>
			</el-form>
		</el-card>

		<el-card class="full-table" shadow="hover" style="margin-top: 8px">
			<el-table :data="state.jobData" style="width: 100%" v-loading="state.loading" border>
				<el-table-column type="expand" fixed>
					<template #default="scope">
						<el-table style="margin-left: 48px; width: calc(100% - 48px)" :data="(scope.row as JobOutput).jobTriggers" border size="small">
							<el-table-column type="index" :label="$t('message.pageConfiguration.number')" width="55" align="center" fixed />
							<el-table-column prop="triggerId" :label="$t('message.pageConfiguration.triggerNo')" width="120" header-align="center" fixed show-overflow-tooltip />
							<el-table-column prop="triggerType" :label="$t('message.pageConfiguration.type')" header-align="center" show-overflow-tooltip />
							<!-- <el-table-column prop="assemblyName" label="程序集" show-overflow-tooltip /> -->
							<el-table-column prop="args" :label="$t('message.pageConfiguration.param')" header-align="center" show-overflow-tooltip />
							<el-table-column prop="description" :label="$t('message.pageConfiguration.desc')" width="120" header-align="center" show-overflow-tooltip />
							<el-table-column prop="status" :label="$t('message.pageConfiguration.status')" width="120" align="center" show-overflow-tooltip>
								<template #default="scope">
									<el-tag type="warning" effect="plain" v-if="(scope.row as SysJobTrigger).status == 0"> {{ $t('message.pageConfiguration.status') }}积压 </el-tag>
									<el-tag type="" effect="plain" v-if="(scope.row as SysJobTrigger).status == 1"> 就绪 </el-tag>
									<el-tag type="success" effect="plain" v-if="(scope.row as SysJobTrigger).status == 2"> 正在运行 </el-tag>
									<el-tag type="danger" effect="plain" v-if="(scope.row as SysJobTrigger).status == 3"> 暂停 </el-tag>
									<el-tag type="danger" effect="plain" v-if="(scope.row as SysJobTrigger).status == 4"> 阻塞 </el-tag>
									<el-tag type="" effect="plain" v-if="(scope.row as SysJobTrigger).status == 5"> 由失败进入就绪 </el-tag>
									<el-tag type="danger" effect="plain" v-if="(scope.row as SysJobTrigger).status == 6"> 归档 </el-tag>
									<el-tag type="danger" effect="plain" v-if="(scope.row as SysJobTrigger).status == 7"> 崩溃 </el-tag>
									<el-tag type="danger" effect="plain" v-if="(scope.row as SysJobTrigger).status == 8"> 超限 </el-tag>
									<el-tag type="danger" effect="plain" v-if="(scope.row as SysJobTrigger).status == 9"> 无触发时间 </el-tag>
									<el-tag type="danger" effect="plain" v-if="(scope.row as SysJobTrigger).status == 10"> 未启动 </el-tag>
									<el-tag type="danger" effect="plain" v-if="(scope.row as SysJobTrigger).status == 11"> 未知作业触发器 </el-tag>
									<el-tag type="danger" effect="plain" v-if="(scope.row as SysJobTrigger).status == 12"> 未知作业处理程序 </el-tag>
								</template>
							</el-table-column>
							<el-table-column prop="startTime" :label="$t('message.pageConfiguration.startTime')" width="100" align="center" show-overflow-tooltip />
							<el-table-column prop="endTime" :label="$t('message.pageConfiguration.endTime')" width="100" align="center" show-overflow-tooltip />
							<el-table-column prop="lastRunTime" :label="$t('message.pageConfiguration.lastRunTime')" width="130" align="center" show-overflow-tooltip />
							<el-table-column prop="nextRunTime" :label="$t('message.pageConfiguration.nextRunTime1')" width="130" align="center" show-overflow-tooltip />
							<el-table-column prop="numberOfRuns" :label="$t('message.pageConfiguration.triggerCount')" width="100" align="center" show-overflow-tooltip />
							<el-table-column prop="maxNumberOfRuns" :label="$t('message.pageConfiguration.maxTriggerCount')" width="120" align="center" show-overflow-tooltip />
							<el-table-column prop="numberOfErrors" :label="$t('message.pageConfiguration.errorCount')" width="100" align="center" show-overflow-tooltip />
							<el-table-column prop="maxNumberOfErrors" :label="$t('message.pageConfiguration.maxErrorCount')" width="120" align="center" show-overflow-tooltip />
							<el-table-column prop="numRetries" :label="$t('message.pageConfiguration.retryCount')" width="100" align="center" show-overflow-tooltip />
							<el-table-column prop="retryTimeout" :label="$t('message.pageConfiguration.retryInterval')" width="100" align="center" show-overflow-tooltip />
							<el-table-column prop="startNow" :label="$t('message.pageConfiguration.startNow')" width="100" align="center" show-overflow-tooltip>
								<template #default="scope">
									<el-tag v-if="(scope.row as SysJobTrigger).startNow == true"> {{ $t('message.pageConfiguration.yes') }} </el-tag>
									<el-tag type="info" v-else> {{ $t('message.pageConfiguration.no') }} </el-tag>
								</template>
							</el-table-column>
							<el-table-column prop="runOnStart" label="$t('message.pageConfiguration.startOnce')" width="150" align="center" show-overflow-tooltip>
								<template #default="scope">
									<el-tag v-if="(scope.row as SysJobTrigger).runOnStart == true"> {{ $t('message.pageConfiguration.yes') }} </el-tag>
									<el-tag type="info" v-else> {{ $t('message.pageConfiguration.no') }} </el-tag>
								</template>
							</el-table-column>
							<el-table-column prop="resetOnlyOnce" label="$t('message.pageConfiguration.resetTriggerCount')" width="120" align="center" show-overflow-tooltip>
								<template #default="scope">
									<el-tag v-if="(scope.row as SysJobTrigger).resetOnlyOnce == true"> {{ $t('message.pageConfiguration.yes') }} </el-tag>
									<el-tag type="info" v-else> {{ $t('message.pageConfiguration.no') }} </el-tag>
								</template>
							</el-table-column>
							<el-table-column prop="updatedTime" :label="$t('message.pageConfiguration.updateTime')" width="130" align="center" show-overflow-tooltip />
							<el-table-column :label="$t('message.pageConfiguration.operate')" width="140" align="center" show-overflow-tooltip fixed="right">
								<template #default="scope">
									<el-tooltip :content="$t('message.pageConfiguration.startTrigger')">
										<el-button size="small" type="primary" icon="ele-VideoPlay" text @click="startTrigger(scope.row)" />
									</el-tooltip>
									<el-tooltip :content="$t('message.pageConfiguration.pauseTrigger')">
										<el-button size="small" type="primary" icon="ele-VideoPause" text @click="pauseTrigger(scope.row)" />
									</el-tooltip>
									<el-tooltip :content="$t('message.pageConfiguration.editTrigger')">
										<el-button size="small" type="primary" icon="ele-Edit" text @click="openEditJobTrigger(scope.row)"> </el-button>
									</el-tooltip>
									<el-tooltip :content="$t('message.pageConfiguration.delTrigger')">
										<el-button size="small" type="danger" icon="ele-Delete" text @click="delJobTrigger(scope.row)"> </el-button>
									</el-tooltip>
								</template>
							</el-table-column>
						</el-table>
					</template>
				</el-table-column>
				<el-table-column type="index" :label="$t('message.pageConfiguration.number')" width="55" align="center" fixed />
				<el-table-column prop="jobDetail.jobId" :label="$t('message.pageConfiguration.jobNumber1')" width="180" header-align="center" fixed>
					<template #default="scope">
						<div style="display: flex; align-items: center">
							<el-icon><timer /></el-icon>
							<span style="margin-left: 5px">{{ (scope.row as JobOutput).jobDetail?.jobId }}</span>
						</div>
					</template>
				</el-table-column>
				<el-table-column prop="jobDetail.groupName" :label="$t('message.pageConfiguration.groupName1')" width="100" align="center" show-overflow-tooltip />
				<el-table-column prop="jobDetail.jobType" :label="$t('message.pageConfiguration.type')" header-align="center" show-overflow-tooltip />
				<!-- <el-table-column prop="jobDetail.assemblyName" label="程序集" show-overflow-tooltip /> -->
				<el-table-column prop="jobDetail.description" :label="$t('message.pageConfiguration.desc')" header-align="center" show-overflow-tooltip />
				<el-table-column prop="jobDetail.concurrent" :label="$t('message.pageConfiguration.execType')" width="90" align="center" show-overflow-tooltip>
					<template #default="scope">
						<el-tag type="success" v-if="(scope.row as JobOutput).jobDetail?.concurrent == true"> {{ $t('message.pageConfiguration.parallel') }} </el-tag>
						<el-tag type="warning" v-else> {{ $t('message.pageConfiguration.serial') }} </el-tag>
					</template>
				</el-table-column>
				<el-table-column prop="jobDetail.createType" :label="$t('message.pageConfiguration.createType')" width="110" align="center" show-overflow-tooltip>
					<template #default="scope">
						<el-tag type="info" v-if="(scope.row as JobOutput).jobDetail?.createType == JobCreateTypeEnum.NUMBER_0"> {{ $t('message.pageConfiguration.built') }} </el-tag>
						<el-tag type="warning" v-if="(scope.row as JobOutput).jobDetail?.createType == JobCreateTypeEnum.NUMBER_1"> {{ $t('message.pageConfiguration.script') }} </el-tag>
						<el-tag type="success" v-if="(scope.row as JobOutput).jobDetail?.createType == JobCreateTypeEnum.NUMBER_2"> {{ $t('message.pageConfiguration.http') }} </el-tag>
					</template>
				</el-table-column>
				<!-- <el-table-column prop="jobDetail.includeAnnotations" label="扫描特性触发器" align="center" show-overflow-tooltip>
					<template #default="scope">
						<el-tag v-if="(scope.row as JobOutput).jobDetail?.includeAnnotations == true"> 是 </el-tag>
						<el-tag v-else> 否 </el-tag>
					</template>
				</el-table-column> -->
				<el-table-column prop="jobDetail.updatedTime" :label="$t('message.pageConfiguration.updateTime')" width="130" align="center" show-overflow-tooltip />
				<el-table-column prop="jobDetail.properties" :label="$t('message.pageConfiguration.extraData')" header-align="center" show-overflow-tooltip>
					<template #default="scope">
						<span v-if="(scope.row as JobOutput).jobDetail?.createType != JobCreateTypeEnum.NUMBER_2"> {{ (scope.row as JobOutput).jobDetail?.properties }} </span>
						<div v-else style="text-align: center">
							<el-popover placement="left" :width="400" trigger="hover">
								<template #reference>
									<el-tag effect="plain" type="info"> {{ $t('message.pageConfiguration.requestParam') }} </el-tag>
								</template>
								<el-descriptions :title="$t('message.pageConfiguration.http1')" :column="1" size="small" :border="true">
									<el-descriptions-item :label="$t('message.pageConfiguration.requestUrl')" label-align="right" label-class-name="job-index-descriptions-label-style">
										{{ getHttpJobMessage((scope.row as JobOutput).jobDetail?.properties).requestUri }}
									</el-descriptions-item>
									<el-descriptions-item :label="$t('message.pageConfiguration.requestMethod')" label-align="right" label-class-name="job-index-descriptions-label-style">
										{{ getHttpMethodDesc(getHttpJobMessage((scope.row as JobOutput).jobDetail?.properties).httpMethod) }}
									</el-descriptions-item>
									<el-descriptions-item :label="$t('message.pageConfiguration.requestMethod')" label-align="right" label-class-name="job-index-descriptions-label-style">
										{{ getHttpJobMessage((scope.row as JobOutput).jobDetail?.properties).body }}
									</el-descriptions-item>
								</el-descriptions>
							</el-popover>
						</div>
					</template>
				</el-table-column>
				<el-table-column :label="$t('message.pageConfiguration.operate')" width="200" fixed="right" align="center" show-overflow-tooltip>
					<template #default="scope">
						<el-tooltip :content="$t('message.pageConfiguration.addTrigger')">
							<el-button size="small" type="primary" icon="ele-CirclePlus" text @click="openAddJobTrigger(scope.row)"> </el-button>
						</el-tooltip>
						<el-tooltip :content="$t('message.pageConfiguration.execJob')">
							<el-button size="small" type="primary" icon="ele-CircleCheck" text @click="runJob(scope.row)" />
						</el-tooltip>
						<el-tooltip :content="$t('message.pageConfiguration.startJob')">
							<el-button size="small" type="primary" icon="ele-VideoPlay" text @click="startJob(scope.row)" />
						</el-tooltip>
						<el-tooltip :content="$t('message.pageConfiguration.pauseJob')">
							<el-button size="small" type="primary" icon="ele-VideoPause" text @click="pauseJob(scope.row)" />
						</el-tooltip>
						<el-tooltip :content="$t('message.pageConfiguration.editJob')">
							<el-button size="small" type="primary" icon="ele-Edit" text @click="openEditJobDetail(scope.row)" v-auth="'sysJob:updateJobDetail'"> </el-button>
						</el-tooltip>
						<el-tooltip :content="$t('message.pageConfiguration.delJob')">
							<el-button size="small" type="danger" icon="ele-Delete" text @click="delJobDetail(scope.row)" v-auth="'sysJob:deleteJobDetail'"> </el-button>
						</el-tooltip>
					</template>
				</el-table-column>
			</el-table>
			<el-pagination
				v-model:currentPage="state.tableParams.page"
				v-model:page-size="state.tableParams.pageSize"
				:total="state.tableParams.total"
				:page-sizes="[10, 20, 50, 100]"
				small
				background
				@size-change="handleSizeChange"
				@current-change="handleCurrentChange"
				layout="total, sizes, prev, pager, next, jumper"
			/>
		</el-card>

		<EditJobDetail ref="editJobDetailRef" :title="state.editJobDetailTitle" @handleQuery="handleQuery" />
		<EditJobTrigger ref="editJobTriggerRef" :title="state.editJobTriggerTitle" @handleQuery="handleQuery" />
		<JobCluster ref="editJobClusterRef" />
	</div>
</template>

<script lang="ts" setup name="sysJob">
import { onMounted, reactive, ref } from 'vue';
import { ElMessageBox, ElMessage } from 'element-plus';
import { useRouter } from 'vue-router';
import { Timer } from '@element-plus/icons-vue';
import EditJobDetail from '/@/views/system/job/component/editJobDetail.vue';
import EditJobTrigger from '/@/views/system/job/component/editJobTrigger.vue';
import JobCluster from '/@/views/system/job/component/jobCluster.vue';

import { getAPI } from '/@/utils/axios-utils';
import { SysJobApi } from '/@/api-services/api';
import { JobCreateTypeEnum, JobOutput, SysJobTrigger } from '/@/api-services/models';
import { useI18n } from 'vue-i18n';

const { t } = useI18n();

const router = useRouter();
const editJobDetailRef = ref<InstanceType<typeof EditJobDetail>>();
const editJobTriggerRef = ref<InstanceType<typeof EditJobTrigger>>();
const editJobClusterRef = ref<InstanceType<typeof JobCluster>>();
const state = reactive({
	loading: false,
	jobData: [] as Array<JobOutput>,
	queryParams: {
		jobId: undefined,
		description: undefined,
	},
	tableParams: {
		page: 1,
		pageSize: 20,
		total: 0 as any,
	},
	editJobDetailTitle: '',
	editJobTriggerTitle: '',
});

onMounted(async () => {
	handleQuery();
});

// 查询操作
const handleQuery = async () => {
	state.loading = true;
	let params = Object.assign(state.queryParams, state.tableParams);
	var res = await getAPI(SysJobApi).apiSysJobPageJobDetailPost(params);
	state.jobData = res.data.result?.items ?? [];
	state.tableParams.total = res.data.result?.total;
	state.loading = false;
};

// 重置操作
const resetQuery = () => {
	state.queryParams.jobId = undefined;
	state.queryParams.description = undefined;
	handleQuery();
};

// 打开新增作业页面
const openAddJobDetail = () => {
	state.editJobDetailTitle = t('message.pageConfiguration.addJob');
	editJobDetailRef.value?.openDialog({ concurrent: true, includeAnnotations: true, groupName: 'default', createType: JobCreateTypeEnum.NUMBER_2 });
};

// 打开编辑作业页面
const openEditJobDetail = (row: JobOutput) => {
	state.editJobDetailTitle = t('message.pageConfiguration.editJob');
	editJobDetailRef.value?.openDialog(row.jobDetail);
};

// 删除作业
const delJobDetail = (row: JobOutput) => {
	ElMessageBox.confirm(t('message.messages.confirmDelJob')+`：【${row.jobDetail?.jobId}】?`, t('message.messages.hint'), {
		confirmButtonText: t('message.pageConfiguration.confirm'),
		cancelButtonText: t('message.pageConfiguration.cancel'),
		type: 'warning',
	})
		.then(async () => {
			await getAPI(SysJobApi).apiSysJobDeleteJobDetailPost({ jobId: row.jobDetail?.jobId });
			handleQuery();
			ElMessage.success(t('message.messages.deleteSuccess'));
		})
		.catch(() => {});
};

// 打开新增触发器页面
const openAddJobTrigger = (row: JobOutput) => {
	state.editJobTriggerTitle = t('message.pageConfiguration.addTrig');
	editJobTriggerRef.value?.openDialog({
		jobId: row.jobDetail?.jobId,
		retryTimeout: 1000,
		startNow: true,
		runOnStart: true,
		resetOnlyOnce: true,
		triggerType: 'Furion.Schedule.PeriodTrigger',
	});
};

// 打开编辑触发器页面
const openEditJobTrigger = (row: SysJobTrigger) => {
	state.editJobTriggerTitle = t('message.pageConfiguration.editTrigger');
	editJobTriggerRef.value?.openDialog(row);
};

// 删除触发器
const delJobTrigger = (row: SysJobTrigger) => {
	ElMessageBox.confirm(t('message.messages.confirmDelTrigger')+`：【${row.triggerId}】?`, t('message.messages.hint'), {
		confirmButtonText: t('message.pageConfiguration.confirm'),
		cancelButtonText: t('message.pageConfiguration.cancel'),
		type: 'warning',
	})
		.then(async () => {
			await getAPI(SysJobApi).apiSysJobDeleteJobTriggerPost({ jobId: row.jobId, triggerId: row.triggerId });
			handleQuery();
			ElMessage.success(t('message.messages.deleteSuccess'));
		})
		.catch(() => {});
};

// 改变页面容量
const handleSizeChange = (val: number) => {
	state.tableParams.pageSize = val;
	handleQuery();
};

// 改变页码序号
const handleCurrentChange = (val: number) => {
	state.tableParams.page = val;
	handleQuery();
};

// 启动所有作业
const startAllJob = async () => {
	await getAPI(SysJobApi).apiSysJobStartAllJobPost();
	ElMessage.success(t('message.messages.startAllJob'));
};

// 暂停所有作业
const pauseAllJob = async () => {
	await getAPI(SysJobApi).apiSysJobPauseAllJobPost();
	ElMessage.success(t('message.messages.pauseAllJob'));
};

// 执行某个作业
const runJob = async (row: JobOutput) => {
	await getAPI(SysJobApi).apiSysJobRunJobPost({ jobId: row.jobDetail?.jobId });
	ElMessage.success(t('message.pageConfiguration.execJob'));
};

// 启动某个作业
const startJob = async (row: JobOutput) => {
	await getAPI(SysJobApi).apiSysJobStartJobPost({ jobId: row.jobDetail?.jobId });
	ElMessage.success(t('message.pageConfiguration.startJob'))	;
};

// 暂停某个作业
const pauseJob = async (row: JobOutput) => {
	await getAPI(SysJobApi).apiSysJobPauseJobPost({ jobId: row.jobDetail?.jobId });
	ElMessage.success(t('message.pageConfiguration.pauseJob'));
};

// 启动触发器
const startTrigger = async (row: SysJobTrigger) => {
	await getAPI(SysJobApi).apiSysJobStartTriggerPost({ jobId: row.jobId, triggerId: row.triggerId });
	ElMessage.success(t('message.pageConfiguration.startTrigger'));
};

// 暂停触发器
const pauseTrigger = async (row: SysJobTrigger) => {
	await getAPI(SysJobApi).apiSysJobPauseTriggerPost({ jobId: row.jobId, triggerId: row.triggerId });
	ElMessage.success(t('message.pageConfiguration.pauseTrigger'));
};

// 强制唤醒作业调度器
const cancelSleep = async () => {
	await getAPI(SysJobApi).apiSysJobCancelSleepPost();
	ElMessage.success(t('message.messages.forceWakeupJob'));
};

// 强制触发所有作业持久化
const persistAll = async () => {
	await getAPI(SysJobApi).apiSysJobPersistAllPost();
	ElMessage.success(t('message.messages.forceTriggerAllJob'));
};

// 打开集群控制页面
const openJobCluster = () => {
	editJobClusterRef.value?.openDrawer();
};

// 打开任务看板
const openJobDashboard = () => {
	router.push({
		path: '/platform/job/dashboard',
	});
};

// 根据任务属性获取 HttpJobMessage
const getHttpJobMessage = (properties: string | undefined | null): HttpJobMessage => {
	if (properties === undefined || properties === null || properties === '') return {};

	const propData = JSON.parse(properties);
	const httpJobMessageNet = JSON.parse(propData['HttpJob']); // 后端大写开头的 HttpJobMessage

	return {
		requestUri: httpJobMessageNet.RequestUri,
		httpMethod: JSON.stringify(httpJobMessageNet.HttpMethod),
		body: httpJobMessageNet.Body,
	};
};

// 获取请求方法的对应描述
const getHttpMethodDesc = (httpMethodStr: string | undefined | null): string => {
	if (httpMethodStr === undefined || httpMethodStr === null || httpMethodStr === '') return '';

	for (const key in editJobDetailRef.value?.httpMethodDef) {
		if (editJobDetailRef.value?.httpMethodDef[key] === httpMethodStr) return key;
	}
	return '';
};
</script>

<style>
/* 此样式不能为 scoped */
.job-index-descriptions-label-style {
	width: 80px;
}
</style>
